package com.fenquen.dfs.router.rocksdb;

import com.fenquen.dfs.base.protocol.data.storage_source.req_from_storage.Report;
import org.rocksdb.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Configuration
public class RocksDBConfig {
    @Autowired
    private RocksDBProp rocksDBProp;

    @Bean
    public RocksDB rocksDB() throws Exception {
        RocksDB.loadLibrary();

        // 先摸索db中目前已有哪些columnFamily
        List<ColumnFamilyDescriptor> currentColumnFamilyDescriptorList = new ArrayList<>();
        List<byte[]> columnFamilyNameByteArrList = RocksDB.listColumnFamilies(new Options().setCreateIfMissing(true), rocksDBProp.home);
        for (byte[] columnFamilyNameByteArr : columnFamilyNameByteArrList) {
            currentColumnFamilyDescriptorList.add(new ColumnFamilyDescriptor(columnFamilyNameByteArr, new ColumnFamilyOptions()));
        }

        // 目标table是不是已在当前的db中,要是没有的话记录
        List<ColumnFamilyDescriptor> needToCreatList = new ArrayList<>();
        for (String tableName : rocksDBProp.tableNameList) {
            boolean found = false;

            // 对比columnFamily名字
            for (ColumnFamilyDescriptor currentColumnFamilyDescriptor : currentColumnFamilyDescriptorList) {
                if (Arrays.equals(currentColumnFamilyDescriptor.getName(), tableName.getBytes(StandardCharsets.UTF_8))) {
                    found = true;
                    break;
                }
            }

            if (found) {
                continue;
            }

            ColumnFamilyDescriptor needToCreate = "FILE_RECORD".equals(tableName) ?
                    new ColumnFamilyDescriptor(tableName.getBytes(StandardCharsets.UTF_8), new ColumnFamilyOptions().
                            useFixedLengthPrefixExtractor(Report.uploadFileUUIDByteLength)) :
                    new ColumnFamilyDescriptor(tableName.getBytes(StandardCharsets.UTF_8), new ColumnFamilyOptions());

            needToCreatList.add(needToCreate);
        }

        // 要是db是空的一个columnFamily都没有,要保证至少要有1个
        if (0 >= currentColumnFamilyDescriptorList.size()) {
            // rocksDB的默认的columnFamily
            currentColumnFamilyDescriptorList.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, new ColumnFamilyOptions()));
        }

        // 调用open函数之后该columnFamilyHandleList会被填充结果
        List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>();
        RocksDB rocksDB = RocksDB.open(new DBOptions().setCreateIfMissing(true), rocksDBProp.home,
                currentColumnFamilyDescriptorList, columnFamilyHandleList);

        // 之前已有的
        for (ColumnFamilyHandle columnFamilyHandle : columnFamilyHandleList) {
            String tableName = new String(columnFamilyHandle.getName());
            if (rocksDBProp.tableNameList.contains(tableName)) {
                rocksDBProp.tableName_columnFamilyHandle.put(tableName, columnFamilyHandle);
            }
        }

        // 需另外新建的columnFamily
        for (ColumnFamilyDescriptor columnFamilyDescriptor : needToCreatList) {
            ColumnFamilyHandle columnFamilyHandle = rocksDB.createColumnFamily(columnFamilyDescriptor);
            rocksDBProp.tableName_columnFamilyHandle.put(new String(columnFamilyHandle.getName()), columnFamilyHandle);
        }

        rocksDBProp.tableName_columnFamilyHandle = Collections.unmodifiableMap(rocksDBProp.tableName_columnFamilyHandle);
        return rocksDB;
    }


}
